package com.common.utils;

import com.model.pojo.device.DevicePcbGpsInfo;
import com.model.vo.device.deviceInfo.getTrackInfo.GetTrackInfoListVO;

import java.util.*;

public class AreaUtil {



    public double handleTrack(List<DevicePcbGpsInfo> gpsList,double trackWidth,String workType) {
        List<GetTrackInfoListVO> trackList = new ArrayList<>();
        List<GetTrackInfoListVO> sameColor = new ArrayList<>();
        List<GetTrackInfoListVO[]> lines = new ArrayList<>();

        GetTrackInfoListVO lastVo = null;
        List<List<GeoPoint>> works=new ArrayList<>();
        List<List<GeoPoint>> countworks=new ArrayList<>();
        if (gpsList != null && gpsList.size() > 0) {
            for (int i = 0; i < gpsList.size(); i++) {
                DevicePcbGpsInfo item = gpsList.get(i);
                GetTrackInfoListVO getTrackInfoListVO = EntityConversionUtil.copy(item, GetTrackInfoListVO.class);
                getTrackInfoListVO.setC(Integer.valueOf(item.getColorIndex()));
                int work=Integer.valueOf(item.getIsWork());
                if(workType.equals("5525")||workType.equals("552c")){
                    if (work < 100||work>500){
                        getTrackInfoListVO.setIsWork("0000");
                        getTrackInfoListVO.setC(0);
                    }

                    else {
                        getTrackInfoListVO.setIsWork("0001");
                        getTrackInfoListVO.setC(1);
                    }
                }else{
                    if (work ==0){
                        getTrackInfoListVO.setIsWork("0000");
                        getTrackInfoListVO.setC(0);
                    }

                    else {
                        getTrackInfoListVO.setIsWork("0001");
                        getTrackInfoListVO.setC(1);
                    }
                }


                if(work!=0){
                    trackList.add(getTrackInfoListVO);
                }

                if(lastVo!=null){
                    if(lastVo.getIsWork().equals("0001")){
                        GeoPoint point1=new GeoPoint(new Double(lastVo.getLat()),new Double(lastVo.getLon()));
                        GeoPoint point2=new GeoPoint(new Double(getTrackInfoListVO.getLat()),new Double(getTrackInfoListVO.getLon()));
                        if(point1.getLongitude()==point2.getLongitude()&&point1.getLatitude()==point2.getLatitude()){

                        }else{

                            List<GeoPoint>points=new ArrayList<>();
                            points.add(point1);
                            points.add(point2);
                            countworks.add(points);

                        }

                    }
                }
                lastVo=getTrackInfoListVO;
                //  trackList.add(getTrackInfoListVO);
            }

        }


        return  calculateWorkArea(countworks,trackWidth);

//
//        ColoredRectanglesAreaCalculator coloredRectanglesAreaCalculator = new ColoredRectanglesAreaCalculator();
//        try {
//            coloredRectanglesAreaCalculator.countArea(trackList);
//        } catch (Exception e) {
//            e.printStackTrace();
//        }


//                if (gpsList != null && gpsList.size() > 0) {
//            for(int i=0;i<gpsList.size();i++){
//                DevicePcbGpsInfo item=gpsList.get(i);
//                GetTrackInfoListVO getTrackInfoListVO = EntityConversionUtil.copy(item, GetTrackInfoListVO.class);
//                getTrackInfoListVO.setC(Integer.valueOf(item.getColorIndex()));
//
//                int work=Integer.valueOf(item.getIsWork());
//                if (Integer.valueOf(item.getIsWork()) < 100)
//                    getTrackInfoListVO.setIsWork("0000");
//                else getTrackInfoListVO.setIsWork("0001");
//
//                if(work==0){
//                    getTrackInfoListVO.setC(0);
//
//                }else{
//                    if(i==0&&work>0){
//                        getTrackInfoListVO.setC(land);
//                    }else{
//                        //工作中的点
//                        if(lastPoint!=null){
//                            double distance=getDistanceM(new Double(lastPoint.getLon()),new Double(lastPoint.getLat()),
//                                    new Double(getTrackInfoListVO.getLon()),new Double(getTrackInfoListVO.getLat()));
//                            double angle=  bearing(lastPoint,getTrackInfoListVO);
//                            getTrackInfoListVO.setAngel(angle);
//                            System.out.println(getTrackInfoListVO.getTime()+"===角度==="+angle+"===距离==="+distance);
//                            if(lastAngel!=-1){
//                                if(lastAngel>=0){
//                                    if(Math.abs(angle-lastAngel)<30){
//
//                                    }else{
//                                        //当前在固定的点，而且上一个点也是工作中，
//                                        if(angle==0&&!lastPoint.getIsWork().equals("0000")&&distance==0){
//
//                                        }else{
//                                            lastAngel=angle;
//                                            land++;
//                                        }
//                                    }
//                                }
//                                getTrackInfoListVO.setC(land);
//                            }else{
//                                getTrackInfoListVO.setC(land);
//                                lastAngel=angle;
//                            }
//
//                        }
//                        lastWorkPosition=i;
//                    }
//                }
//                lastPoint=getTrackInfoListVO;
//          //      trackList.add(getTrackInfoListVO);
//                if(getTrackInfoListVO.getC()!=0){
//                    if(sameColor.size()==0){
//                        sameColor.add(getTrackInfoListVO);
//                    }else{
//                        if(sameColor.get(0).getC()==getTrackInfoListVO.getC()){//当与上一点相同时，则加入队列
//                            sameColor.add(getTrackInfoListVO);
//                        }else{//不同，则添加首尾两个点到数据中
//                            if(sameColor.size()==1){
//                                sameColor.clear();
//                                sameColor.add(getTrackInfoListVO);
//                            }else{
//                                double distance= getDistanceM(new Double(sameColor.get(0).getLon()),new Double(sameColor.get(0).getLat()),
//                                        new Double(sameColor.get(1).getLon()),new Double(sameColor.get(1).getLat()));
//                                if(distance<0.01){
//                                    sameColor.clear();
//                                    continue;
//                                }
//                                trackList.add(sameColor.get(0));
//                                trackList.add(sameColor.get(sameColor.size()-1));
//                                GetTrackInfoListVO[] line={sameColor.get(0),sameColor.get(sameColor.size()-1)};
//                                lines.add(line);
//                                sameColor.clear();
//                                sameColor.add(getTrackInfoListVO);
//
//                            }
//                        }
//                    }
//                }
//
//            }
//
//        }
//        if(sameColor.size()>1){
//            double distance= getDistanceM(new Double(sameColor.get(0).getLon()),new Double(sameColor.get(0).getLat()),
//                    new Double(sameColor.get(1).getLon()),new Double(sameColor.get(1).getLat()));
//            if(distance>0.01){
//                trackList.add(sameColor.get(0));
//                trackList.add(sameColor.get(sameColor.size()-1));
//                GetTrackInfoListVO[] line={sameColor.get(0),sameColor.get(sameColor.size()-1)};
//                lines.add(line);
//                sameColor.clear();
//            }
//
//        }
//        trackList= handleLines(lines);

        //     return trackList;
    }





    private static double convertToMu(double area) {
        return area / 666.67;
    }

    // 计算两个经纬度点之间的距离（单位：米）
    private static double calculateDistance(double lat1, double lon1, double lat2, double lon2) {
        double R = 6371000; // 地球半径，单位：米
        double phi1 = Math.toRadians(lat1);
        double phi2 = Math.toRadians(lat2);
        double deltaPhi = Math.toRadians(lat2 - lat1);
        double deltaLambda = Math.toRadians(lon2 - lon1);

        double a = Math.sin(deltaPhi / 2) * Math.sin(deltaPhi / 2) +
                Math.cos(phi1) * Math.cos(phi2) *
                        Math.sin(deltaLambda / 2) * Math.sin(deltaLambda / 2);
        double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));

        return R * c;
    }
    // 计算线段的长度（单位：米）
    private static double calculateLineLength(List<GeoPoint> line) {
        double length = 0.0;
        int numPoints = line.size();
        for (int i = 0; i < numPoints - 1; i++) {
            GeoPoint currentPoint = line.get(i);
            GeoPoint nextPoint = line.get(i + 1);
            double lat1 = currentPoint.getLatitude();
            double lon1 = currentPoint.getLongitude();
            double lat2 = nextPoint.getLatitude();
            double lon2 = nextPoint.getLongitude();
            length += calculateDistance(lat1, lon1, lat2, lon2);
        }
        return length;
    }


    // 计算农机作业的总面积和重叠的面积
    public double  calculateWorkArea(List<List<GeoPoint>> trackPoints, double trackWidth) {
        double totalArea = 0.0;
        double overlappingArea = 0.0;

        for (List<GeoPoint> line : trackPoints) {
            double lineLength = calculateLineLength(line);
            double lineArea = lineLength * trackWidth;
            totalArea += lineArea;
            // 判断线段与其他线段的重叠情况
//            for (List<GeoPoint> otherLine : trackPoints) {
//                if (otherLine != line) {
//                    boolean isOverlapping = checkLineOverlapping(line, otherLine, trackWidth);
//                    if (isOverlapping) {
//                        overlappingArea += lineArea;
//                        break;
//                    }
//                }
//            }
        }

        return convertToMu(totalArea);

    }


    // 检查两条线段是否重叠
    private static boolean checkLineOverlapping(List<GeoPoint> line1, List<GeoPoint> line2, double trackWidth) {
        Set<GeoPoint> pointsSet = new HashSet<>(line1);
        for (int i = 0; i < line2.size() - 1; i++) {
            GeoPoint startPoint = line2.get(i);
            GeoPoint endPoint = line2.get(i + 1);
            double distance = calculateLineLength(createLineSegment(startPoint, endPoint));

            // 检查线段上的点是否在集合中
            for (double t = 0; t <= 1; t += 0.1) {
                double lat = startPoint.getLatitude() + (endPoint.getLatitude() - startPoint.getLatitude()) * t;
                double lon = startPoint.getLongitude() + (endPoint.getLongitude() - startPoint.getLongitude()) * t;
                GeoPoint point = new GeoPoint(lat, lon);

                if (pointsSet.contains(point)) {
                    return true;
                }

                // 检查线段两侧的点
                double perpendicularDistance = trackWidth / 2;
                double angle = Math.atan2(endPoint.getLatitude() - startPoint.getLatitude(),
                        endPoint.getLongitude() - startPoint.getLongitude());

                double latLeft = lat + perpendicularDistance * Math.sin(angle);
                double lonLeft = lon - perpendicularDistance * Math.cos(angle);
                GeoPoint pointLeft = new GeoPoint(latLeft, lonLeft);

                double latRight = lat - perpendicularDistance * Math.sin(angle);
                double lonRight = lon + perpendicularDistance * Math.cos(angle);
                GeoPoint pointRight = new GeoPoint(latRight, lonRight);
                if (pointsSet.contains(pointLeft) || pointsSet.contains(pointRight)) {
                    return true;
                }
            }

            // 检查线段两个端点是否在集合中
            if (pointsSet.contains(startPoint) || pointsSet.contains(endPoint)) {
                return true;
            }
        }
        return false;
    }


    private static List<GeoPoint> createLineSegment(GeoPoint startPoint, GeoPoint endPoint) {
        List<GeoPoint> lineSegment = new ArrayList<>();
        lineSegment.add(startPoint);
        lineSegment.add(endPoint);
        return lineSegment;
    }



}

